using Microsoft.AspNetCore.Mvc;
using SmartMedicalRAG.Core.Models;
using SmartMedicalRAG.Core.Services;

namespace SmartMedicalRAG.Api.Controllers;

/// <summary>
/// 分诊控制器 - 智能医疗分诊系统的核心控制器
/// 作用：处理患者数据，通过 RAG 技术生成智能分诊建议
/// 功能：多模态数据处理、智能分析、分诊建议生成、结果验证
/// 路由：/api/triage
/// </summary>
[ApiController]
[Route("api/[controller]")]
public class TriageController : ControllerBase
{
    private readonly IRAGGenerationService _ragService;           // RAG 生成服务 - 负责检索增强生成
    private readonly IMultimodalDataService _multimodalService;   // 多模态数据服务 - 处理文本、语音、图像等
    private readonly ILogger<TriageController> _logger;           // 日志记录器

    /// <summary>
    /// 构造函数 - 依赖注入初始化
    /// 作用：接收并初始化所需的服务依赖
    /// </summary>
    /// <param name="ragService">RAG 生成服务</param>
    /// <param name="multimodalService">多模态数据处理服务</param>
    /// <param name="logger">日志记录器</param>
    public TriageController(
        IRAGGenerationService ragService,
        IMultimodalDataService multimodalService,
        ILogger<TriageController> logger)
    {
        _ragService = ragService;
        _multimodalService = multimodalService;
        _logger = logger;
    }

    /// <summary>
    /// 详细分诊分析 - 完整的分诊处理流程
    /// 作用：接收患者数据，进行多模态处理，生成详细的分诊建议
    /// 访问路径：POST /api/triage/analyze
    /// 处理流程：数据预处理 → 多模态分析 → RAG 检索 → 智能生成 → 结果验证
    /// 输入：患者主诉、症状、病史、多模态数据（文本、语音、图像、生理信号）
    /// 输出：分诊建议、置信度、追溯来源、验证结果
    /// 使用场景：完整的患者评估、复杂病例分析、需要详细分诊建议的情况
    /// </summary>
    /// <param name="request">患者分析请求 - 包含所有患者相关数据</param>
    /// <returns>分诊响应 - 包含智能分析结果和建议</returns>
    /// <response code="200">成功返回分诊分析结果</response>
    /// <response code="400">请求数据格式错误或缺少必要信息</response>
    /// <response code="500">服务器内部错误或 AI 服务异常</response>
    [HttpPost("analyze")]
    [ProducesResponseType(typeof(TriageResponse), 200)]
    [ProducesResponseType(400)]
    [ProducesResponseType(500)]
    public async Task<ActionResult<TriageResponse>> AnalyzePatientAsync([FromBody] PatientAnalysisRequest request)
    {
        return await ProcessTriageRequest(request, "analyze");
    }

    /// <summary>
    /// 快速分诊分析 - 简化版分诊处理
    /// 作用：提供快速的分诊分析，适用于紧急情况或初步筛查
    /// 访问路径：POST /api/triage
    /// 特点：处理速度更快，适合初步分诊和紧急情况
    /// 输入：患者基本信息（主诉、症状等）
    /// 输出：快速分诊建议和紧急程度评估
    /// 使用场景：急诊分诊、初步筛查、快速评估、移动端应用
    /// </summary>
    /// <param name="request">患者分析请求</param>
    /// <returns>分诊响应</returns>
    /// <response code="200">成功返回快速分诊结果</response>
    /// <response code="400">请求数据格式错误</response>
    /// <response code="500">服务器内部错误</response>
    [HttpPost]
    [ProducesResponseType(typeof(TriageResponse), 200)]
    [ProducesResponseType(400)]
    [ProducesResponseType(500)]
    public async Task<ActionResult<TriageResponse>> AnalyzePatientRootAsync([FromBody] PatientAnalysisRequest request)
    {
        return await ProcessTriageRequest(request, "root");
    }

    /// <summary>
    /// 分诊请求处理的核心方法 - 统一处理逻辑
    /// 作用：封装所有分诊处理的核心逻辑，包括数据验证、多模态处理、RAG 生成等
    /// 处理步骤：
    /// 1. 数据验证和预处理
    /// 2. 多模态数据处理（文本、语音、图像、生理信号）
    /// 3. 构建患者数据模型
    /// 4. 调用 RAG 服务生成分诊建议
    /// 5. 验证生成结果的准确性
    /// 6. 获取追溯来源（支持结果解释）
    /// 7. 返回完整的分析结果
    /// </summary>
    /// <param name="request">患者分析请求</param>
    /// <param name="source">请求来源标识（"analyze" 或 "root"）</param>
    /// <returns>分诊响应</returns>
    private async Task<ActionResult<TriageResponse>> ProcessTriageRequest(PatientAnalysisRequest request, string source)
    {
        try
        {
            // 记录请求开始，便于追踪和调试
            _logger.LogInformation("收到{Source}分诊分析请求，患者主诉: {ChiefComplaint}", source, request.ChiefComplaint ?? "无主诉");
            
            // 步骤1：处理多模态数据 - 支持文本、语音、图像、生理信号
            var processedData = new List<ProcessedData>();
            
            // 处理文本数据（患者主诉、病史等）
            if (!string.IsNullOrEmpty(request.TextData))
            {
                var textData = await _multimodalService.ProcessTextAsync(request.TextData);
                processedData.Add(textData);
            }
            
            // 处理语音数据（患者语音描述）
            if (request.VoiceData != null)
            {
                var voiceData = await _multimodalService.ProcessVoiceAsync(request.VoiceData);
                processedData.Add(voiceData);
            }
            
            // 处理图像数据（医学影像、皮肤病变等）
            if (request.ImageData != null)
            {
                var imageData = await _multimodalService.ProcessImageAsync(request.ImageData);
                processedData.Add(imageData);
            }
            
            // 处理生理信号数据（心电图、血压、体温等）
            if (request.PhysiologicalData != null)
            {
                var signalData = await _multimodalService.ProcessPhysiologicalSignalAsync(request.PhysiologicalData);
                processedData.Add(signalData);
            }
            
            // 步骤2：构建完整的患者数据模型
            var patientData = new PatientData
            {
                ChiefComplaint = request.ChiefComplaint ?? "患者未提供主诉",
                Symptoms = request.Symptoms ?? new List<string>(),
                VitalSigns = request.VitalSigns,
                MedicalHistory = request.MedicalHistory,
                ProcessedData = processedData
            };
            
            // 步骤3：调用 RAG 服务生成智能分诊建议
            var recommendation = await _ragService.GenerateTriageRecommendationAsync(patientData);
            
            // 步骤4：验证生成建议的准确性和可靠性
            var isValid = await _ragService.ValidateRecommendationAsync(recommendation);
            
            // 步骤5：获取追溯来源，支持结果解释和审计
            var sources = await _ragService.GetTraceabilitySourcesAsync(recommendation);
            
            // 步骤6：构建完整的响应结果
            var response = new TriageResponse
            {
                Recommendation = recommendation,
                IsValid = isValid,
                TraceabilitySources = sources,
                ProcessingTime = DateTime.UtcNow,
                Confidence = recommendation.Confidence
            };
            
            // 记录处理完成，包含关键结果信息
            _logger.LogInformation("{Source}分诊分析完成，推荐科室: {Department}, 置信度: {Confidence}", 
                source, recommendation.RecommendedDepartment, recommendation.Confidence);
            
            return Ok(response);
        }
        catch (Exception ex)
        {
            // 异常处理和日志记录
            _logger.LogError(ex, "{Source}分诊分析失败", source);
            return StatusCode(500, new { error = "分诊分析失败", message = ex.Message });
        }
    }

    /// <summary>
    /// 系统健康状态检查 - 服务可用性监控
    /// 作用：检查分诊服务的运行状态，用于健康检查和负载均衡
    /// 访问路径：GET /api/triage/health
    /// 用途：系统监控、服务发现、负载均衡器健康检查
    /// 返回：服务状态、时间戳、版本信息
    /// 使用场景：运维监控、服务健康检查、负载均衡器配置
    /// </summary>
    /// <returns>健康状态信息</returns>
    /// <response code="200">系统正常运行</response>
    /// <response code="503">系统服务不可用</response>
    [HttpGet("health")]
    [ProducesResponseType(typeof(HealthStatus), 200)]
    [ProducesResponseType(503)]
    public ActionResult<HealthStatus> GetHealthStatus()
    {
        return Ok(new HealthStatus
        {
            Status = "Healthy",
            Timestamp = DateTime.UtcNow,
            Version = "1.0.0"
        });
    }

    /// <summary>
    /// 分诊服务测试端点 - 功能验证和调试
    /// 作用：验证分诊服务的基本功能，提供端点信息用于调试和测试
    /// 访问路径：GET /api/triage/test
    /// 用途：开发调试、功能验证、API 文档说明
    /// 返回：测试结果、可用端点列表、时间戳
    /// 使用场景：开发测试、API 功能验证、集成测试
    /// </summary>
    /// <returns>测试响应和端点信息</returns>
    /// <response code="200">测试成功，返回端点信息</response>
    [HttpGet("test")]
    [ProducesResponseType(200)]
    public ActionResult<object> GetTest()
    {
        return Ok(new
        {
            message = "Triage API 测试成功",
            timestamp = DateTime.UtcNow,
            endpoints = new
            {
                analyze = "POST /api/triage/analyze",
                root = "POST /api/triage",
                health = "GET /api/triage/health"
            }
        });
    }
}

/// <summary>
/// 患者分析请求模型 - 定义分诊分析所需的输入数据
/// 作用：规范客户端请求的数据格式，确保数据完整性和一致性
/// 包含：患者基本信息、症状描述、多模态数据等
/// 用途：作为所有分诊分析端点的统一输入格式
/// </summary>
/// <summary>
/// 患者分析请求模型 - 定义客户端请求的数据格式
/// 作用：规范客户端请求的数据结构，确保数据完整性和一致性
/// 包含：患者基本信息、症状、生命体征、多模态数据等
/// 用途：作为所有分诊分析端点的统一输入格式
/// 
/// 示例请求：
/// {
///   "chiefComplaint": "头痛、恶心、呕吐，持续3天",
///   "symptoms": ["头痛", "恶心", "呕吐", "发热", "食欲不振"],
///   "vitalSigns": {
///     "bloodPressure": "140/90",
///     "heartRate": 85,
///     "temperature": 38.2,
///     "respiratoryRate": 18,
///     "oxygenSaturation": 96
///   },
///   "medicalHistory": "高血压病史5年，糖尿病史2年，对青霉素过敏",
///   "textData": "患者主诉头痛，伴有恶心呕吐，体温38.2°C，血压140/90mmHg",
///   "voiceData": null,
///   "imageData": null,
///   "physiologicalData": {
///     "type": "ECG",
///     "values": [72, 75, 78, 71, 74, 76, 73, 75, 77, 72],
///     "timestamps": ["2024-01-15T10:00:00Z", "2024-01-15T10:01:00Z"],
///     "unit": "bpm"
///   }
/// }
/// </summary>
public class PatientAnalysisRequest
{
    /// <summary>
    /// 患者主诉 - 患者的主要症状描述
    /// 作用：记录患者的主要不适症状，是分诊的重要依据
    /// 示例："头痛、恶心、呕吐"
    /// </summary>
    public string? ChiefComplaint { get; set; }
    
    /// <summary>
    /// 症状列表 - 患者的所有症状
    /// 作用：详细记录患者的各种症状，用于综合分析
    /// 示例：["头痛", "恶心", "呕吐", "发热"]
    /// </summary>
    public List<string> Symptoms { get; set; } = new();
    
    /// <summary>
    /// 生命体征 - 患者的生理指标
    /// 作用：记录血压、心率、体温等关键生理指标
    /// 包含：血压、心率、体温、呼吸频率等
    /// </summary>
    public VitalSigns? VitalSigns { get; set; }
    
    /// <summary>
    /// 病史 - 患者的既往病史
    /// 作用：记录患者的疾病史、过敏史、用药史等
    /// 用途：辅助判断当前症状与既往疾病的关系
    /// </summary>
    public string? MedicalHistory { get; set; }
    
    /// <summary>
    /// 文本数据 - 结构化的文本信息
    /// 作用：接收医生记录、患者描述等文本信息
    /// 处理：通过 NLP 技术进行语义分析和实体提取
    /// </summary>
    public string? TextData { get; set; }
    
    /// <summary>
    /// 语音数据 - 患者语音描述
    /// 作用：接收患者的语音输入，转换为文本进行分析
    /// 格式：音频文件字节数组
    /// 处理：语音识别 → 文本转换 → 语义分析
    /// </summary>
    public byte[]? VoiceData { get; set; }
    
    /// <summary>
    /// 图像数据 - 医学影像或照片
    /// 作用：接收医学影像、皮肤病变照片等图像数据
    /// 格式：图像文件字节数组
    /// 处理：图像分割 → 特征提取 → 病变识别
    /// </summary>
    public byte[]? ImageData { get; set; }
    
    /// <summary>
    /// 生理数据 - 生理信号数据
    /// 作用：接收心电图、血压监测、体温等生理信号
    /// 包含：时间序列数据、信号特征等
    /// 处理：异常检测 → 时间序列分析 → 趋势预测
    /// </summary>
    public PhysiologicalData? PhysiologicalData { get; set; }
}

/// <summary>
/// 分诊响应模型 - 定义分诊分析的结果数据
/// 作用：规范服务端响应的数据格式，提供完整的分析结果
/// 包含：分诊建议、置信度、追溯来源等
/// 用途：作为所有分诊分析端点的统一输出格式
/// 
/// 示例响应：
/// {
///   "recommendation": {
///     "recommendedDepartment": "神经内科",
///     "priority": "Urgent",
///     "reasoning": "患者出现头痛、恶心、呕吐等症状，伴有发热，需要排除颅内感染",
///     "confidence": 0.85,
///     "traceabilitySources": ["头痛诊断指南", "脑膜炎临床路径"]
///   },
///   "isValid": true,
///   "traceabilitySources": [
///     "《神经病学》第8版 - 头痛章节",
///     "《急诊医学》第6版 - 神经系统急症",
///     "相似病例数据库 - 病例ID: 2024001"
///   ],
///   "processingTime": "2024-01-15T10:30:00Z",
///   "confidence": 0.85
/// }
/// </summary>
public class TriageResponse
{
    /// <summary>
    /// 分诊建议 - 智能分析的核心结果
    /// 作用：包含推荐科室、紧急程度、处理建议等
    /// 内容：科室推荐、紧急程度、处理优先级、注意事项
    /// </summary>
    public TriageRecommendation Recommendation { get; set; } = new();
    
    /// <summary>
    /// 结果有效性 - 建议的可靠性评估
    /// 作用：标识生成建议的准确性和可靠性
    /// 用途：帮助医生判断是否采纳 AI 建议
    /// </summary>
    public bool IsValid { get; set; }
    
    /// <summary>
    /// 追溯来源 - 支持结果解释的证据
    /// 作用：提供支持分诊建议的医学依据和知识来源
    /// 内容：医学文献、临床指南、相似病例等
    /// 用途：增强医生对 AI 建议的信任度
    /// </summary>
    public List<string> TraceabilitySources { get; set; } = new();
    
    /// <summary>
    /// 处理时间 - 分析完成的时间戳
    /// 作用：记录分析完成的时间，用于性能监控和审计
    /// 格式：UTC 时间戳
    /// </summary>
    public DateTime ProcessingTime { get; set; }
    
    /// <summary>
    /// 置信度 - 建议的可靠程度
    /// 作用：量化分诊建议的可靠程度（0-1 之间）
    /// 用途：帮助医生评估建议的可信度
    /// 示例：0.85 表示 85% 的置信度
    /// </summary>
    public float Confidence { get; set; }
}

/// <summary>
/// 健康状态模型 - 定义服务健康检查的响应格式
/// 作用：标准化健康检查的响应格式
/// 包含：服务状态、时间戳、版本信息
/// 用途：系统监控、健康检查、负载均衡器配置
/// 
/// 示例响应：
/// {
///   "status": "Healthy",
///   "timestamp": "2024-01-15T10:30:00Z",
///   "version": "1.0.0"
/// }
/// 
/// 状态说明：
/// - Healthy: 服务正常运行
/// - Unhealthy: 服务异常，需要关注
/// - Degraded: 服务降级，部分功能不可用
/// </summary>
public class HealthStatus
{
    /// <summary>
    /// 服务状态 - 当前服务的运行状态
    /// 作用：标识服务是否正常运行
    /// 可能值：Healthy（健康）、Unhealthy（不健康）、Degraded（降级）
    /// </summary>
    public string Status { get; set; } = string.Empty;
    
    /// <summary>
    /// 时间戳 - 健康检查的时间
    /// 作用：记录健康检查的执行时间
    /// 格式：UTC 时间戳
    /// </summary>
    public DateTime Timestamp { get; set; }
    
    /// <summary>
    /// 版本信息 - 当前服务的版本号
    /// 作用：标识服务的版本，便于版本管理和问题追踪
    /// 格式：语义化版本号（如 1.0.0）
    /// </summary>
    public string Version { get; set; } = string.Empty;
} 